#include "ESP8266_MQTT.h"

#include <Arduino.h>

// 构造函数
ESP8266_MQTT::ESP8266_MQTT(int rxPin, int txPin, const char* ssid,
                           const char* password)
    : esp8266(rxPin, txPin), ssid(ssid), password(password) {}

// 初始化
void ESP8266_MQTT::begin(long baudRate) { esp8266.begin(baudRate); }

// 连接 WiFi
void ESP8266_MQTT::connectWiFi() {
    char command[100];
    sprintf(command, "AT+CWJAP=\"%s\",\"%s\"", ssid, password);
    sendATCommand(command, 10000);
}

// 配置 MQTT 用户信息
void ESP8266_MQTT::configMQTTUser(const char* clientId, const char* user,
                                  const char* password) {
    String command = "AT+MQTTUSERCFG=0,1,\"" + String(clientId) + "\",\"" +
                     String(user) + "\",\"" + String(password) + "\",0,0,\"\"";
    sendATCommand(command.c_str(), 2000);
}

// 连接 MQTT 服务器
void ESP8266_MQTT::connectMQTT(const char* server, int port) {
    String command =
        "AT+MQTTCONN=0,\"" + String(server) + "\"," + String(port) + ",1";
    sendATCommand(command.c_str(), 5000);
}

// 订阅主题
void ESP8266_MQTT::subscribe(const char* topic, int qos) {
    String command = "AT+MQTTSUB=0,\"" + String(topic) + "\"," + String(qos);
    sendATCommand(command.c_str(), 2000);
}

// 发布消息
void ESP8266_MQTT::publish(const char* topic, const char* message, int qos,
                           int retain) {
    char command[100];
    sprintf(command, "AT+MQTTPUB=0,\"%s\",\"%s\",%d,%d", topic, message, qos,
            retain);
    sendATCommand(command, 2000);
}

// 监听 MQTT 消息
bool ESP8266_MQTT::listen(String& topic, String& payload) {
    while (esp8266.available()) {
        String response = esp8266.readStringUntil('\n');

        // 如果是订阅的消息, 解析 MQTT 消息
        if (response.startsWith("+MQTTSUBRECV")) {
            // Receive: +MQTTSUBRECV:0,"ssl/app/mode",6,3
            Serial.print("Receive: ");
            Serial.println(response);

            // 获取topic
            int start = response.indexOf('\"') + 1;   // 找到 topic 的起始位置
            int end = response.indexOf('\"', start);  // 找到 topic 的结束位置
            topic = response.substring(start, end);   // 提取 topic

            // 找到消息内容的起始位置
            int payloadStart = response.lastIndexOf(',') + 1;
            payload = response.substring(payloadStart);

            return true;
        } else {
            Serial.print("Other response: ");
            Serial.println(response);
        }
    }

    return false;
}

// 发送 AT 指令
void ESP8266_MQTT::sendATCommand(const char* command, unsigned long timeout) {
    Serial.print("Send: ");
    Serial.println(command);

    esp8266.println(command);  // 发送指令

    // 等待响应
    unsigned long time = millis();
    while ((time + timeout) > millis()) {
        while (esp8266.available()) {
            String response = esp8266.readString();
            Serial.print("Receive: ");
            Serial.println(response);
        }
    }
}
